\chapter{Object Oriented Design}
%
The CEAB++ system is implemented using the Python programming language. Python
provides facilities for object oriented programming, allowing a number of
object oriented principles to be applied to the design process. A number of
object oriented design principles were explored when implementing the CEAB++
system, including: the Open/Closed Principle, the Dependency Inversion
Principle, and the Interface Segregation Principle. Ultimately, it was found
that the dynamic nature of Python precluded the need for many of these
principles which were largely created in response to common problems
encountered by developers working in statically typed languages such as C++ and
Java.

\section{Open/Closed Principle}
%
The Open/Closed Principle was first proposed by Bertrand Meyer in 1988. The
principle states, ``Software entities should be open for extension, but closed
for modification''~\cite{ref:openClosed}. Effectively, the principle states that in
order to improve code quality and reuse, well designed object oriented code
must make use of immutable abstract interfaces, different implementations (or
extensions) to a given software entity can be created by implementing a given
interface or producing a new interface which inherits a pre-existing interface.
It is believed that code which obeys the open/closed principle does not change
when it is extended, reducing the need for regression testing and other
costly review processes.

In dynamic languages such as Python, there is no syntactic method to enforce the
open/closed principle, as the language lacks constructs such as interfaces.
However, the language provides facilities for multiple inheritance, allowing the
open/closed principle to be upheld by means of inheriting pre-existing entities
(i.e. classes) and overriding methods as necessary. Due in part to the lack of
necessary language features, the open/closed principle does not find much use
throughout Python code. The python community instead encourages thorough
automated testing by means of unit tests to provide similar benefits to those
offered by the open/closed principle. The open/closed principle is not followed
in the software developed for the PyCEAB application.

\section{Dependency Inversion Principle}
%
The dependency inversion principle states that ``high level modules should not
depend upon low level modules''~\cite{ref:di}. Dependency inversion discourages the
traditional software engineering convention which recommends high level modules
depend upon lower level modules--producing tightly coupled systems.  By
eliminating `hard coded' dependencies between high and low level modules, the
principle encourages a very loose coupling between code. A system designed with
dependency inversion in mind allows low level modules to be passed into a high
level module dynamically, via a process called dependency injection. Dependency
injection provides a way to design high level modules such that they can be
easily reused or adapted for use with other low level modules. As well, by
allowing low-level dependencies to be defined at runtime, it is much easier to
dynamically change the behaviour of a given high level method either for the
purposes of testing or adding additional functionality.

In statically typed languages such as Java and C++, dependency injection is
accomplished by means of a special dependency injection framework. However,
dynamic languages such as Python provide facilities for `duck typing', i.e.
determining an object's type by inspection of its method or attribute
signature rather than its inheritance from a particular class or interface.
Duck typing provides all of the necessary functionality for producing code
according to the dependency inversion principle without the need for any
external libraries or frameworks.

    \section{Interface Segregation Principle}
Clients should not depend on interfaces that they do not use. This technique
simplifies the interface that a client uses and removes dependencies that might
otherwise develop on parts of the interface that are not needed. 

``Fat'' interfaces arise from classes whose member methods can be broken into
two or more groups. Each group of methods in turn serves a different set of
clients. The Interface Segregation Principle suggests that client should not
know about the method groups as a single class. Instead, clients should only
know about abstract base classes, one for each method group.

This can be harmful, since changes in one single class interface can propagate
through the system. When additional functionality is added, other clients need
to change to support the functionality, even though that particular method group
is not used. Interface segregation is used wherever possible to reduce code
maintenance and ease bug tracking.
 
\section{Composition Over Inheritance}

Object composition and inheritance are two techniques for reusing functionality
in object-oriented programming. Inheritance or subclassing extends a class'
functionality by defining an implementation in terms of the parent class. Termed
white-box re-use since the implementation of the parent class is visible to the
child class. In composition, on the other hand, the internals of the object are
unknown and the interface well defined. Object composition possesses advantages
as the implementation is decoupled and the resulting inheritance hierarchy is
smaller. 

Both forms of re-use are necessary. Object composition or black-box re-use is
favored over inheritance wherever the additional flexibility is warranted.


